package com.dony.shop.service.impl;

import com.dony.common.utils.SecurityUtils;
import com.dony.shop.domain.*;
import com.dony.shop.domain.vo.PublishShopVo;
import com.dony.shop.util.ShopeeUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dony.common.utils.StringUtils;
import com.dony.shop.domain.enums.ShopeeCountryEnum;
import com.dony.shop.domain.vo.GlobalProductVo;
import com.dony.shop.domain.vo.PriceVo;
import com.dony.shop.domain.vo.RpcPriceBody;
import com.dony.shop.mapper.GlobalProductMapper;
import com.dony.shop.service.*;
import com.dony.shop.util.PriceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

/**
 * 全球商品业务层处理
 *
 * @author sundw
 * @date 2022-03-08
 */
@Slf4j
@Service("globalProductService")
public class GlobalProductServiceImpl extends ServiceImpl<GlobalProductMapper, GlobalProduct> implements IGlobalProductService {

    @Autowired
    ShopeeUtil shopeeUtil;
    @Resource
    IPriceConfigService priceConfigService;
    @Resource
    IGlobalModelService globalModelService;
    @Resource
    IShopeeMerchantService merchantService;
    @Resource
    IItemService itemService;
    @Resource
    IShopeeShopService shopService;
    @Resource
    ThreadPoolTaskExecutor executor;


    /**
     * 定时更新所有全球商品
     */
    public void refreshAllGlobalItem() {
        List<ShopeeMerchant> merchants = merchantService.list();
        for (ShopeeMerchant merchant : merchants) {
            syncGlobalItemListByMerchantId(merchant.getMerchantId());
        }
        List<ShopeeShop> localShops = shopService.list(new QueryWrapper<ShopeeShop>().isNull("merchant_id"));
        for (ShopeeShop shop : localShops) {
            executor.execute(() -> {
                itemService.syncShopItemByShopId(null, null, shop.getShopId());
            });
        }
    }


    @Override
    public Boolean syncGlobalItemList(Long merchantId) {
        //同步全部
        Long updateTimeTo = System.currentTimeMillis() / 1000L;
        Long updateTimeFrom = updateTimeTo - 60 * 60 * 24 * 3 * 1L;
        return syncGlobalItemListByMerchantId(merchantId, updateTimeFrom, updateTimeTo);
    }

    @Transactional
    public Boolean syncGlobalItemListByMerchantId(Long merchantId, Long updateTimeFrom, Long updateTimeTo) {
        QueryWrapper<GlobalProduct> removeWp = new QueryWrapper<GlobalProduct>().eq("merchant_id", merchantId);
        if (updateTimeFrom != null && updateTimeTo != null) {
            removeWp.between("update_time",new Date(updateTimeFrom),new Date(updateTimeTo));
        }
        this.remove(removeWp);
        Long tenantId = merchantService.getTenantByMerchant(merchantId);
        Boolean hasNextPage = false;
        String offset = "";
        do {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("page_size", 20);
            paramMap.put("offset", offset);
            if (updateTimeFrom != null && updateTimeTo != null) {
                paramMap.put("update_time_from", updateTimeFrom);
                paramMap.put("update_time_to", updateTimeTo);
            }
            JSONObject response = shopeeUtil.merchantGetHandler("/api/v2/global_product/get_global_item_list", merchantId, paramMap);
            if (response == null) {
                hasNextPage = false;
                continue;
            }
            hasNextPage = response.getBoolean("has_next_page");
            offset = response.getString("offset");
            List<JSONObject> globalPros = response.getList("global_item_list", JSONObject.class);
            for (JSONObject pro : globalPros) {
                Long globalItemId = pro.getLong("global_item_id");
                executor.execute(() -> {
                    List<GlobalProduct> globalProducts = getGlobalItemInfo(merchantId, tenantId, new Long[]{globalItemId});
                });
                executor.execute(() -> {
                    //更新产品已经已经发布的店铺商品
                    List<PublishShopVo> pulishedShop = this.getPulishedShop(merchantId, globalItemId);
                    for (PublishShopVo item : pulishedShop) {
                        itemService.syncShopItemByItemId(tenantId, item.getMerchantId(), item.getShopId(), item.getItemId());
                    }
                });
            }
        } while (hasNextPage);
        log.info("商户:{}的全球商品信息更新完成", merchantId);
        return true;
    }

    @Override
    @Transactional
    public Boolean syncGlobalItemListByMerchantId(Long merchantId) {
        return syncGlobalItemListByMerchantId(merchantId, null, null);
    }


    @Override
    public List<GlobalProductVo> getVoListByParam(GlobalProductVo globalProductVo) {
        GlobalProduct gp = new GlobalProduct();
        BeanUtils.copyProperties(globalProductVo, gp);
        List<GlobalProduct> listByParam = this.getListByParam(gp);
        return this.pakageVoList(listByParam, false);
    }

    /**
     * 把数据封装成vo
     *
     * @param originList
     * @param needPrice
     * @return
     */
    @Override
    public List<GlobalProductVo> pakageVoList(List<GlobalProduct> originList, boolean needPrice) {
        List<GlobalProductVo> globalProductVos = new ArrayList<>();
        originList.forEach(gloPro -> {
            GlobalProductVo productVo = new GlobalProductVo();
            BeanUtils.copyProperties(gloPro, productVo);
            //集合价格
            Map<Float, StringBuilder> priceMap = new HashMap<>();
            List<GlobalModel> skuList = globalModelService.list(new QueryWrapper<GlobalModel>().eq("global_item_id", gloPro.getGlobalItemId()));
            skuList.forEach(sku -> {
                StringBuilder sb = priceMap.get(sku.getOriginalPrice());
                if (sb == null) {
                    sb = new StringBuilder();
                }
                sb.append(sku.getGlobalModelSku()).append("、");
                priceMap.put(sku.getOriginalPrice(), sb);
            });
            List<PriceVo> priceVoList = new ArrayList<>();
            priceMap.forEach((k, v) -> {
                PriceVo priceVo = new PriceVo();
                //这是设置全球价格备用
                priceVo.setGlobalPrice(k);
                priceVo.setSkuStr(v.toString());
                priceVo.setWeight(productVo.getWeight());
                //设置原始价格
                priceVo.setOrigenPrice(PriceUtil.getPriceByName(productVo.getGlobalItemSku()));
                //设置商品Id
                priceVo.setGlobalItemId(productVo.getGlobalItemId());
                //分别查询价格
                if (needPrice) {
                    priceVo = setContryPrice(productVo.getMerchantId(), priceVo);
                }
                //封装
                priceVoList.add(priceVo);
            });
            //封装到页面
            //如果只有一个
            if (priceVoList.size() == 1) {
                productVo.setPrice(priceVoList.get(0));
                productVo.setHasChildren(false);
                //productVo.setPriceList(priceVoList);
                globalProductVos.add(productVo);
            } else if (priceVoList.size() > 1) {
                productVo.setPrice(priceVoList.get(0));
                productVo.setHasChildren(true);
                //productVo.setPriceList(priceVoList);
                globalProductVos.add(productVo);
                //专门给页面使用的数据
                for (int i = 1; i < priceVoList.size(); i++) {
                    GlobalProductVo globalProductVo = new GlobalProductVo();
                    globalProductVo.setGlobalItemName("└──────▶");
                    globalProductVo.setHasChildren(false);
                    globalProductVo.setParentId(productVo.getGlobalItemId());
                    globalProductVo.setWeight(productVo.getWeight());
                    globalProductVo.setPrice(priceVoList.get(i));
                    globalProductVos.add(globalProductVo);
                }
            }
        });
        return globalProductVos;
    }


    /**
     * 获取已经发布的店铺
     *
     * @param merchantId
     * @param globalItemId
     * @return
     */
    @Override
    public List<PublishShopVo> getPulishedShop(Long merchantId, Long globalItemId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("global_item_id", globalItemId);
        JSONObject response = shopeeUtil.merchantGetHandler("/api/v2/global_product/get_published_list", merchantId, paramMap);
        if (response == null) {
            return null;
        }
        List<JSONObject> publishedShops = response.getList("published_item", JSONObject.class);
        if (publishedShops == null) {
            return null;
        }
        List<PublishShopVo> shops = publishedShops.stream().map(shop -> {
            PublishShopVo publishShopVo = new PublishShopVo();
            publishShopVo.setShopId(shop.getLong("shop_id"));
            publishShopVo.setMerchantId(merchantId);
            publishShopVo.setShopRegion(shop.getString("shop_region"));
            publishShopVo.setItemId(shop.getLong("item_id"));
            //已发布项目的状态。适用的值:0。已删除(Item由卖家本人删除)，1.正常,2.禁止,3.检查4。无效(Shopee管理员删除),5。6.黑名单(Offensive_hide)，8.NORMAL_UNLIST (normal_unlist)
            publishShopVo.setItemStatus(shop.getInteger("item_status"));
            publishShopVo.setStatus(1);
            return publishShopVo;
        }).collect(Collectors.toList());
        return shops;
    }


    /**
     * 获取商品的可发布的店铺
     *
     * @param merchantId
     * @param globalItemId
     * @return
     */
    @Override
    public List<PublishShopVo> getPulishedShopList(Long merchantId, Long globalItemId) {
        List<PublishShopVo> pulishedShop = getPulishedShop(merchantId, globalItemId);
        List<ShopeeShop> shopList = shopService.getPublishShopListByMerchant(merchantId);

        List<PublishShopVo> publishedShopVos = shopList.stream().map(shop -> {
            PublishShopVo publishShopVo = new PublishShopVo();
            pulishedShop.forEach(s -> {
                if (shop.getShopId().equals(s.getShopId())) {
                    BeanUtils.copyProperties(s, publishShopVo);
                }
            });
            if (publishShopVo.getShopId() == null) {
                publishShopVo.setShopRegion(shop.getRegion());
                publishShopVo.setMerchantId(merchantId);
                publishShopVo.setShopId(shop.getShopId());
                publishShopVo.setStatus(0);
            }
            return publishShopVo;
        }).collect(Collectors.toList());
        return publishedShopVos;
    }


    /**
     * 获取单个可以发布的店铺
     *
     * @param merchantId
     * @param globalItemId
     * @return
     */
    public List<PublishShopVo> getPulishableShop(Long merchantId, Long globalItemId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("global_item_id", globalItemId);
        JSONObject response = shopeeUtil.merchantGetHandler("/api/v2/global_product/get_publishable_shop", merchantId, paramMap);
        if (response == null) {
            return null;
        }
        List<JSONObject> publishableShops = response.getList("publishable_shop", JSONObject.class);
        if (publishableShops == null) {
            return null;
        }
        List<PublishShopVo> shops = publishableShops.stream().map(shop -> {
            PublishShopVo publishShopVo = new PublishShopVo();
            publishShopVo.setShopId(shop.getLong("shop_id"));
            publishShopVo.setShopRegion(shop.getString("shop_region"));
            return publishShopVo;
        }).collect(Collectors.toList());
        return shops;
    }

    @Override
    public List<GlobalProductVo> getPriceList(GlobalProduct globalProduct, Long[] ids) {
        //后期处理这个 globalProduct 的参数设置
        QueryWrapper<GlobalProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("global_item_id", Arrays.asList(ids));
        List<GlobalProduct> list = this.list(queryWrapper);
        return this.pakageVoList(list, true);
    }


    @Override
    public PriceVo setContryPrice(Long merchantId, PriceVo vo) {
        return setContryPrice(merchantId, vo, null);
    }

    @Override
    public PriceVo setContryPrice(Long merchantId, PriceVo vo, List<String> countrys) {
        //如果没有商户Id ，就去查询
        if (merchantId == null) {
            GlobalProduct globalProduct = this.getById(vo.getGlobalItemId());
            merchantId = globalProduct.getMerchantId();
        }
        if (merchantId == null) return null;
        PriceConfig priceConfig = priceConfigService.selectPriceConfigByMerchantId(merchantId);
        JSONObject priceJo = JSON.parseObject(JSON.toJSONString(vo));
        JSONObject pcJo = JSON.parseObject(JSON.toJSONString(priceConfig));
//        Map<String, Object> pcMap = JSON.parseObject(JSON.toJSONString(priceConfig), new TypeReference<Map<String, Object>>() {
//        });
        ShopeeCountryEnum[] values = ShopeeCountryEnum.values();
        if (countrys != null) {
            //只查询需要发布的地区
            values = Arrays.stream(values).filter(val -> {
                return countrys.contains(val.getCapital());
            }).toArray(ShopeeCountryEnum[]::new);
        }
        for (ShopeeCountryEnum value : values) {
            //当前站点code
            Integer maolilv = (Integer) pcJo.get(value.getCountry());
            RpcPriceBody rpcPriceBody = new RpcPriceBody();
            rpcPriceBody.setPurchasePrice(Math.round(vo.getOrigenPrice()));
            rpcPriceBody.setMaolilv(maolilv.toString());
            rpcPriceBody.setSite(value.getRpc());
            rpcPriceBody.setmWeight(vo.getWeight().toString());
            //折扣目前统一配置为20
            rpcPriceBody.setZhekou(priceConfig.getDiscount().toString());
            rpcPriceBody.setFss(priceConfig.getFss() ? "1" : "0");
            rpcPriceBody.setCcb(priceConfig.getCcb() ? "1" : "0");
            rpcPriceBody = priceConfigService.getPriceByRpc(rpcPriceBody);
            //取整
            //Integer price = Math.round(rpcPriceBody.getSellPrice());
            if (rpcPriceBody.getSellPrice() != null) {
                //对价格进行高位取整100
                Integer price = PriceUtil.fomatToInteger(rpcPriceBody.getSellPrice());
                priceJo.put(value.getCountry(), price);
            }
        }
        return priceJo.to(PriceVo.class);
    }


    @Override
    public GlobalProductVo getLinePriceDetail(GlobalProductVo productVo) {
        productVo.setPrice(this.setContryPrice(productVo.getMerchantId(), productVo.getPrice()));
        return productVo;
    }


    @Override
    public List<GlobalProduct> getListByParam(GlobalProduct globalProduct) {
//        if (globalProduct == null || globalProduct.getMerchantId() == null) {
//            return null;
//        }
        LambdaQueryWrapper<GlobalProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GlobalProduct::getMerchantId, globalProduct.getMerchantId());
        if (StringUtils.isNotEmpty(globalProduct.getGlobalItemName())) {
            wrapper.and(w -> {
                w.eq(GlobalProduct::getGlobalItemId, globalProduct.getGlobalItemName().trim())
                        .or()
                        .like(GlobalProduct::getGlobalItemName, globalProduct.getGlobalItemName().trim());
            });
        }
        if (StringUtils.isNotEmpty(globalProduct.getGlobalItemSku())) {
            wrapper.like(GlobalProduct::getGlobalItemSku, globalProduct.getGlobalItemSku());
        }
        //匹配租户ID
        wrapper.eq(GlobalProduct::getTenantId, SecurityUtils.getDeptId());
        wrapper.orderByDesc(GlobalProduct::getUpdateTime);
        return list(wrapper);
    }


    @Override
    public List<GlobalProduct> getGlobalItemInfo(Long merchantId, Long tenantId, Long[] proIds) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("global_item_id_list", proIds);
        JSONObject response = shopeeUtil.merchantGetHandler("/api/v2/global_product/get_global_item_info", merchantId, paramMap);
        if (response == null) {
            return null;
        }
        List<JSONObject> globalPros = (List<JSONObject>) response.get("global_item_list");
        List<GlobalProduct> globalProductList = globalPros.stream().map(product -> {
            GlobalProduct globalProduct = new GlobalProduct();
            globalProduct.setMerchantId(merchantId);
            globalProduct.setTenantId(tenantId);
            globalProduct.setGlobalItemId(product.getLong("global_item_id"));
            globalProduct.setGlobalItemName(product.getString("global_item_name"));
            globalProduct.setDescription(product.getString("description"));
            globalProduct.setGlobalItemSku(product.getString("global_item_sku"));
            globalProduct.setGlobalItemStatus(product.getString("global_item_status"));
            globalProduct.setCreateTime(new Date(product.getLong("create_time") * 1000L));
            globalProduct.setUpdateTime(new Date(product.getLong("update_time") * 1000L));
            //首图
            globalProduct.setImageUrl(product.getJSONObject("image").getList("image_url_list", String.class).get(0));
            String imageId = product.getJSONObject("image").getList("image_id_list", String.class).get(0);
            globalProduct.setImageMini("https://s-cf-sg.shopeesz.com/file/" + imageId + "_tn");
            globalProduct.setWeight(product.getFloat("weight"));
            globalModelService.syncGlobalModel(merchantId, globalProduct.getGlobalItemId());
            return globalProduct;
        }).collect(Collectors.toList());
        if (globalProductList != null && globalProductList.size() != 0) {
            this.saveOrUpdateBatch(globalProductList);
            return globalProductList;
        }
        return null;
    }


    /**
     * 获取价格的json对象
     *
     * @return
     */
    @Override
    public JSONObject getPriceJo(PriceVo priceVo) {
        //如果没有查询价格
        if (priceVo.getMy() == null) {
            GlobalProduct product = this.getById(priceVo.getGlobalItemId());
            List<ShopeeShop> publishShops = shopService.getPublishShopListByMerchant(product.getMerchantId());
            //设置需要发布的店铺
            List<String> countrys = publishShops.stream().map(shop -> {
                return shop.getRegion();
            }).collect(Collectors.toList());
            priceVo = this.setContryPrice(null, priceVo, countrys);
        }
        return JSON.parseObject(JSON.toJSONString(priceVo));
    }

}
